﻿using Alipay.AopSdk.Core;
using Alipay.AopSdk.Core.Domain;
using Alipay.AopSdk.Core.Request;
using Alipay.AopSdk.Core.Util;
using LPP.Entity.Orders;
using LPP.Service.OrderServices;
using LPP.Service.Payment;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using LPP.Entity.Exceptions;


using LPP.Core.Alipay;
using LPP.Repository.PaymentRecordRepository;
using LPP.Entity.PaymentRecord;
using System.Text.Json;

namespace LPP.Service.payment;

public class AlipayService : IAlipayService
{
    private readonly IAopClient _client;
    private readonly AlipayConfig _config;
    private readonly IOrderService _orderService;
    private readonly ILogger<AlipayService> _logger;
    private readonly IPaymentRecordRepository _paymentRecordRepository;
    private readonly JsonSerializerOptions _jsonOptions;


    public AlipayService(
        IOptions<AlipayConfig> config,
        IPaymentRecordRepository paymentRecordRepository,
        IOrderService orderService,
        ILogger<AlipayService> logger)
    {
        _config = config.Value;
        _orderService = orderService;
        _logger = logger;
        _paymentRecordRepository = paymentRecordRepository;

        _client = new DefaultAopClient(
            _config.GatewayUrl,
            _config.AppId,
            _config.PrivateKey,
            _config.Format,
            _config.Version,
            _config.SignType,
            _config.PublicKey,
            _config.Charset,
            false);
    }

    public async Task<string> CreatePaymentAsync(Order order)
    {
        try
        {
            // 1. 创建支付模型
            var model = new AlipayTradeWapPayModel
            {
                OutTradeNo = order.OrderID,
                TotalAmount = order.Amount.ToString("0.00"),
                Subject = $"维修服务订单-{order.OrderID}",
                Body = order.Description ?? "维修服务费用",
                ProductCode = "QUICK_WAP_PAY",
                TimeoutExpress = "30m",
                GoodsType = "1" // 虚拟商品
            };

            // 2. 创建支付请求
            var request = new AlipayTradeWapPayRequest();
            request.SetBizModel(model);
            request.SetNotifyUrl(_config.NotifyUrl);
            request.SetReturnUrl(_config.ReturnUrl);

            // 3. 调用支付宝接口
            var response = await Task.Run(() => _client.Execute(request));

            if (response.IsError)
            {
                _logger.LogError(
                    "创建支付宝订单失败: OrderId={OrderId}, ErrorCode={ErrorCode}, ErrorMsg={ErrorMsg}",
                    order.OrderID,
                    response.SubCode,
                    response.SubMsg
                );
                throw new PaymentException($"创建支付宝订单失败: {response.SubMsg}");
            }

            // 4. 记录支付请求
            await SavePaymentRecord(order, model, response.Body);

            return response.Body;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建支付宝支付失败: OrderId={OrderId}", order.OrderID);
            throw new PaymentException("创建支付宝支付失败", ex);
        }
    }

    public bool VerifyNotify(Dictionary<string, string> parameters)
    {
        try
        {
            return AlipaySignature.RSACheckV1(
                parameters,
                _config.PublicKey,
                _config.Charset,
                _config.SignType,
                false);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "验证支付宝通知签名失败");
            return false;
        }
    }

    public async Task<bool> VerifyPaymentAsync(string orderId, string tradeNo)
    {
        try
        {
            var request = new AlipayTradeQueryRequest();
            var model = new AlipayTradeQueryModel
            {
                OutTradeNo = orderId,
                TradeNo = tradeNo
            };

            request.SetBizModel(model);

            var response = await Task.Run(() => _client.Execute(request));

            if (!response.IsError)
            {
                _logger.LogInformation(
                    "支付宝订单查询成功: OrderId={OrderId}, TradeStatus={TradeStatus}",
                    orderId,
                    response.TradeStatus
                );
                return response.TradeStatus == "TRADE_SUCCESS";
            }

            _logger.LogWarning(
                "支付宝订单查询失败: OrderId={OrderId}, ErrorCode={ErrorCode}, ErrorMsg={ErrorMsg}",
                orderId,
                response.SubCode,
                response.SubMsg
            );

            return false;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "查询支付宝订单状态失败: OrderId={OrderId}, TradeNo={TradeNo}",
                orderId,
                tradeNo
            );
            return false;
        }
    }

    public async Task<bool> HandlePaymentNotifyAsync(Dictionary<string, string> parameters)
    {
        try
        {
            if (!parameters.TryGetValue("out_trade_no", out var orderId) ||
                !parameters.TryGetValue("trade_status", out var tradeStatus))
            {
                return false;
            }

            var order = await _orderService.GetOrderByIdAsync(orderId);
            if (order == null || order.Status == OrderStatus.Completed)
            {
                return false;
            }

            if (tradeStatus == "TRADE_SUCCESS")
            {
                order.Status = OrderStatus.Completed;
                order.PaidAt = DateTime.Now;
                order.PaymentMethod = PaymentMethod.Alipay;
                order.TransactionId = parameters["trade_no"];
                order.PaymentInfo = JsonSerializer.Serialize(parameters);

                await _orderService.UpdateOrderAsync(order);
                return true;
            }

            return false;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理支付宝通知失败: {@Parameters}", parameters);
            return false;
        }
    }

    private async Task SavePaymentRecord(Order order, AlipayTradeWapPayModel model, string response)
    {
        var record = new PaymentRecord
        {
            OrderId = order.OrderID,
            Amount = order.Amount,
            PaymentMethod = PaymentMethod.Alipay,
            Status = PaymentStatus.Pending,
            CreatedAt = DateTime.Now,
            RequestData = JsonSerializer.Serialize(model),
            ResponseData = response
        };

        await _paymentRecordRepository.AddAsync(record);
    }
}
